]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
extensionSystem: Split out loadExtensionMetadata()
authorFlorian Müllner <fmuellner@gnome.org>
Sun, 21 Jan 2024 22:31:31 +0000 (23:31 +0100)
committerMarge Bot <marge-bot@gnome.org>
Wed, 16 Oct 2024 16:16:08 +0000 (16:16 +0000)
There is no need for sharing the functionality, but moving
the code into extensionUtils allows adding unit tests for it.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3379>

js/misc/extensionUtils.js
js/ui/extensionSystem.js

index 09338a182e4c1e8d23d30994691876ea6fc4a447..2d47a38108bed9fc7c3b8060c55bdf93d037891f 100644 (file)
@@ -109,3 +109,64 @@ export function deserializeExtension(variant) {
     res.dir = Gio.File.new_for_path(res.path);
     return res;
 }
+
+/**
+ * Load extension metadata from directory
+ *
+ * @param {string} uuid of the extension
+ * @param {GioFile} dir to load metadata from
+ * @returns {object}
+ */
+export function loadExtensionMetadata(uuid, dir) {
+    const dirName = dir.get_basename();
+    if (dirName !== uuid)
+        throw new Error(`Directory name "${dirName}" does not match UUID "${uuid}"`);
+
+    const metadataFile = dir.get_child('metadata.json');
+    if (!metadataFile.query_exists(null))
+        throw new Error('Missing metadata.json');
+
+    let metadataContents, success_;
+    try {
+        [success_, metadataContents] = metadataFile.load_contents(null);
+        metadataContents = new TextDecoder().decode(metadataContents);
+    } catch (e) {
+        throw new Error(`Failed to load metadata.json: ${e}`);
+    }
+    let meta;
+    try {
+        meta = JSON.parse(metadataContents);
+    } catch (e) {
+        throw new Error(`Failed to parse metadata.json: ${e}`);
+    }
+
+    const requiredProperties = [{
+        prop: 'uuid',
+        typeName: 'string',
+    }, {
+        prop: 'name',
+        typeName: 'string',
+    }, {
+        prop: 'description',
+        typeName: 'string',
+    }, {
+        prop: 'shell-version',
+        typeName: 'string array',
+        typeCheck: v => Array.isArray(v) && v.length > 0 && v.every(e => typeof e === 'string'),
+    }];
+    for (let i = 0; i < requiredProperties.length; i++) {
+        const {
+            prop, typeName, typeCheck = v => typeof v === typeName,
+        } = requiredProperties[i];
+
+        if (!meta[prop])
+            throw new Error(`missing "${prop}" property in metadata.json`);
+        if (!typeCheck(meta[prop]))
+            throw new Error(`property "${prop}" is not of type ${typeName}`);
+    }
+
+    if (uuid !== meta.uuid)
+        throw new Error(`UUID "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
+
+    return meta;
+}
index 9b5b944b6b477f79afd975e2cb9b3b802648bfb6..ece089bfd8e1962258065d5db588eb69e3e7035f 100644 (file)
@@ -8,7 +8,9 @@ import * as Signals from '../misc/signals.js';
 import * as Config from '../misc/config.js';
 import * as ExtensionDownloader from './extensionDownloader.js';
 import {formatError} from '../misc/errorUtils.js';
-import {ExtensionState, ExtensionType} from '../misc/extensionUtils.js';
+import {
+    ExtensionState, ExtensionType, loadExtensionMetadata
+} from '../misc/extensionUtils.js';
 import * as FileUtils from '../misc/fileUtils.js';
 import * as Main from './main.js';
 import * as MessageTray from './messageTray.js';
@@ -377,55 +379,10 @@ export class ExtensionManager extends Signals.EventEmitter {
     }
 
     createExtensionObject(uuid, dir, type) {
-        let metadataFile = dir.get_child('metadata.json');
-        if (!metadataFile.query_exists(null))
-            throw new Error('Missing metadata.json');
-
-        let metadataContents, success_;
-        try {
-            [success_, metadataContents] = metadataFile.load_contents(null);
-            metadataContents = new TextDecoder().decode(metadataContents);
-        } catch (e) {
-            throw new Error(`Failed to load metadata.json: ${e}`);
-        }
-        let meta;
-        try {
-            meta = JSON.parse(metadataContents);
-        } catch (e) {
-            throw new Error(`Failed to parse metadata.json: ${e}`);
-        }
-
-        const requiredProperties = [{
-            prop: 'uuid',
-            typeName: 'string',
-        }, {
-            prop: 'name',
-            typeName: 'string',
-        }, {
-            prop: 'description',
-            typeName: 'string',
-        }, {
-            prop: 'shell-version',
-            typeName: 'string array',
-            typeCheck: v => Array.isArray(v) && v.length > 0 && v.every(e => typeof e === 'string'),
-        }];
-        for (let i = 0; i < requiredProperties.length; i++) {
-            const {
-                prop, typeName, typeCheck = v => typeof v === typeName,
-            } = requiredProperties[i];
-
-            if (!meta[prop])
-                throw new Error(`missing "${prop}" property in metadata.json`);
-            if (!typeCheck(meta[prop]))
-                throw new Error(`property "${prop}" is not of type ${typeName}`);
-        }
-
-        if (uuid !== meta.uuid)
-            throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
-
-        let extension = {
-            metadata: meta,
-            uuid: meta.uuid,
+        const metadata = loadExtensionMetadata(uuid, dir);
+        const extension = {
+            metadata,
+            uuid,
             type,
             dir,
             path: dir.get_path(),
@@ -434,7 +391,7 @@ export class ExtensionManager extends Signals.EventEmitter {
             enabled: this._enabledExtensions.includes(uuid),
             hasUpdate: false,
             canChange: false,
-            sessionModes: meta['session-modes'] ? meta['session-modes'] : ['user'],
+            sessionModes: metadata['session-modes'] ?? ['user'],
         };
         this._extensions.set(uuid, extension);